package com.newopenlab.hmc.util;

import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import com.newopenlab.hmc.biz.Player;

public class BasicParser {
	public static String HEADER_TABLETYPE_PRE=":  ";
	public static String HEADER_TABLETYPE_POST=" [";
	public static String HEADER_TABLETYPE1_PRE="' ";
	public static String HEADER_TABLETYPE1_POST=" Seat";
	public static String HEADER_HAND_PRE="PokerStars Hand #";
	public static String HEADER_HAND_POST=":";
	
	public static String HEADER_PREFLOP_PRE="*** HOLE CARDS ***";
	
	public static String HEADER_HEADER_DATE_PRE=" - ";
	public static String HEADER_HEADER_DATE_POST="CET";
	public static String HEADER_HEADER_TABLENAME_PRE="Table '";
	public static String HEADER_HEADER_TABLENAME_POST="' ";
	public static String HEADER_HEADER_BUTTONSEAT_PRE="#";
	public static String HEADER_HEADER_BUTTONSEAT_POST=" is the";
	
	public static String HEADER_SEAT_PRE="Seat ";
	public static String HEADER_SEAT_POST=": ";
	public static String HEADER_PLAYER_POST=" (";
	
	public static String HEADER_PLAYERCHIPS_PRE="(";
	public static String HEADER_PLAYERCHIPS_POST=" in chips";
	public static String HEADER_SUMMARY_PRE="*** SUMMARY ***";
	public static String HEADER_SUMMARY_TOTAL_POT_PRE="Total pot "; 
	public static String HEADER_SUMMARY_TOTAL_POT_POST=" | "; 
	public static String HEADER_ACTION_PLAYER_POST=": ";
	public static String HEADER_WAY_FLOP_PRE="*** FLOP *** [";
	public static String HEADER_WAY_TURN_PRE="*** TURN *** [";
	public static String HEADER_WAY_RIVER_PRE="*** RIVER *** [";
	public static String HEADER_WAY_POST="]";
	
	public static String HEADER_UNCALLED_BET_PRE="Uncalled bet (";
	public static String HEADER_UNCALLED_BET_POST=") returned to ";
	
	public File inputFile=null;
	public SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
	public NumberFormat nf=NumberFormat.getInstance(Locale.US);
	
	public String getStringIn(String target,String start,String end){
		String res=null;
		int st=target.indexOf(start);
		int en=target.indexOf(end);
		if(st>=0 && en>=0 && en>st){
			res=target.substring(st+start.length(), en);
		}
		return res;
	}
	
	public String getStringIn(String target,String start,String end,int sDelay){
		String res=null;
		int st=target.indexOf(start);
		int en=target.indexOf(end);
		if(st>=0 && en>=0 && en>st){
			res=target.substring(st+start.length()+sDelay, en);
		}
		return res;
	}
	
	public String getStringBefore(String target,String end){
		String res=null;
		int en=target.indexOf(end);
		if(en>=0){
			res=target.substring(0,en);
		}
		return res;
	}
	
	public String getStringAfter(String target,String start,int sDelay){
		String res=null;
		int st=target.indexOf(start);
		if(st>=0){
			res=target.substring(st+start.length()+sDelay);
		}
		return res;
	}
	
	public String getStringAfter(String target,String start){
		String res=null;
		res=this.getStringAfter(target, start, 0);
		return res;
	}
	
	public List<BaseHand> readBaseHands(){
		List<BaseHand> res=null;
		LinesExtractor le=new LinesExtractor();
		le.inputFile=inputFile;
		
		List<String> rows=null;
		Set<Integer> delimeters=null;
		Set<Integer> flopDelimeters=null;
		Set<Integer> turnDelimeters=null;
		Set<Integer> riverDelimeters=null;
		List<Integer> preflopDelimeters=null;
		List<Integer> summaryDelimeters=null;
		int pfdIndex=0;
		int pfd=0;
		int summaryd=0;
		int summaryIdx=0;
		res=new ArrayList<BaseHand>();
		try {
			rows = le.extract();
			delimeters=new HashSet<Integer>(le.getHandDelimeters(rows));
			flopDelimeters=new HashSet<Integer>(le.getHandFlopDelineters(rows));
			turnDelimeters=new HashSet<Integer>(le.getHandTurnDelineters(rows));
			riverDelimeters=new HashSet<Integer>(le.getHandRiverDelineters(rows));
			preflopDelimeters=le.getHandPreflopDelineters(rows);
			summaryDelimeters=le.getSummaryDelineters(rows);
			String header=null;
			BaseHand bh=null;
			ActionParser ap=new ActionParser();
			SummaryParser sp=new SummaryParser();
			String code=null;
			Way w=Way.PREFLOP;
			for(int i=0;i<rows.size();i++){
				
				if(delimeters.contains(i)){
					w=Way.PREFLOP;
					pfd=preflopDelimeters.get(pfdIndex++);
					summaryd=summaryDelimeters.get(summaryIdx++);
					header=rows.get(i);
					bh=new BaseHand();
					ap.basicParser=this;
					ap.bh=bh;
					sp.basicParser=this;
					sp.bh=bh;
					bh.code=this.getStringIn(header,HEADER_HAND_PRE,HEADER_HAND_POST);
					bh.tableType=this.getStringIn(header,HEADER_TABLETYPE_PRE,HEADER_TABLETYPE_POST);
					if(header.contains("PokerStars") && header.contains("AAMS")){
						bh.site="Pokerstars.it";
					}
					try {
						bh.time=this.sdf.parse(this.getStringIn(header, HEADER_HEADER_DATE_PRE, HEADER_HEADER_DATE_POST));
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					res.add(bh);
				}else if(delimeters.contains(i-1)){
					String secondLine=rows.get(i);
					bh.tablename=this.getStringIn(secondLine, HEADER_HEADER_TABLENAME_PRE, HEADER_HEADER_TABLENAME_POST);
					bh.buttonSeat=Integer.parseInt(this.getStringIn(secondLine, HEADER_HEADER_BUTTONSEAT_PRE, HEADER_HEADER_BUTTONSEAT_POST));
					bh.tableType+=this.getStringIn(secondLine,HEADER_TABLETYPE1_PRE,HEADER_TABLETYPE1_POST);
				}else if(i<pfd){
					String aux=rows.get(i);
					String aux1=null;
					if((aux1=this.getStringIn(aux, HEADER_SEAT_PRE, HEADER_SEAT_POST))!=null){
						Player p=new Player();
						
						bh.seats.put(aux1, p);
						aux1=this.getStringIn(aux, HEADER_SEAT_POST,HEADER_PLAYER_POST);
						p.name=aux1;
						PlayerHandResult phr=new PlayerHandResult();
						phr.p=p;
						bh.results.put(p.name, phr);
						aux1=this.getStringIn(aux, HEADER_PLAYERCHIPS_PRE,HEADER_PLAYERCHIPS_POST,1);
						try {
							p.chips=nf.parse(aux1).doubleValue();
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}else{
						WayAction wa=ap.parse(aux);
						
						if(wa!=null){
							wa.way=w.getName();
							bh.actions.add(wa);
						}else{
							bh.lines.add(rows.get(i));
							
						}
					}
					
				}else if(i>summaryd){
					String aux=rows.get(i);
					String aux1=null;
					aux1=this.getStringIn(aux, HEADER_SUMMARY_TOTAL_POT_PRE,HEADER_SUMMARY_TOTAL_POT_POST,1);
					if(aux1!=null){
						try {
							bh.totalPot=nf.parse(aux1).doubleValue();
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}else{
						sp.parse(aux);
					}
				}else{
					
					if(flopDelimeters.contains(i)){
						w=Way.FLOP;
					}else if(turnDelimeters.contains(i)){
						w=Way.TURN;
					}else if(riverDelimeters.contains(i)){
						w=Way.RIVER;
					}else{
						WayAction wa=ap.parse(rows.get(i));
						
						if(wa!=null){
							wa.way=w.getName();
							bh.actions.add(wa);
						}else{
							if(!ap.filterUncalledBets(rows.get(i))){
								bh.lines.add(rows.get(i));
							}
						}
					}
					
					
					
				}
				
			}
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
		return res;
	}
	
	
	
	
}
